/**
 * Written By: MinHo Kim (minho.kim.korea@gmail.com)
 * Copyright (C) 2011, MinHo Kim, Software Expert Program, KAIST University, Seoul, Korea.
 * This program is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU General Public License as published 
 * by the Free Software Foundation; version 2 of the License.
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 * See the GNU General Public License for more details.
 */
package kaist.sep502.tsp.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;

import kaist.sep502.tsp.model.City;

/**
 * @author minho kim
 *
 */
public class TspUtil {
	/**
	 * Vector형 객체를 deep copy하여 리턴한다.
	 */
	public synchronized static Vector<Object> cloneForDeepCopy(Vector<Object> objects){
		Vector<Object> newObjects = new Vector<Object>(objects.size());
		Enumeration<Object> e = objects.elements();
		
		while(e.hasMoreElements()){
			Object o = e.nextElement();
			newObjects.addElement(TspUtil.cloneForDeepCopy(o));
		}
		
		return newObjects;
	}
	
	public synchronized static Object cloneForDeepCopy(Object object){
		@SuppressWarnings("rawtypes")
		Class c = object.getClass();
		Object newObject = null;
		try{
			newObject = c.newInstance();
		} catch(Exception e){
			System.out.println("TspUtil.cloneForDeepCopy 오류");
			e.printStackTrace();
			return null;
		}
		
		Field[] field = c.getFields();
		for(int i=0; i<field.length; i++){
			try{
				Object f = field[i].get(object);
				field[i].set(newObject, f);
			} catch(Exception e){
				System.out.println("TspUtil.cloneForDeepCopy 오류");
				e.printStackTrace();
				return null;
			}
		}
		
		return newObject;
	}
	
	public synchronized static double formatDouble(double value){
		return ((int) (value * 10000000)) / 10000000.0; 
	}
	
	public synchronized static int convertInt(double value){
		return ((int) (value * 10000000));
	}
	
	public synchronized static double getScreenPoint(double screenMax, double point){
		double iPoint = point * 10.0;
		double multiply = screenMax / 10.0;
		return iPoint * multiply;
	}

	/**
	 * @param filePath
	 * @return
	 * @throws Exception 
	 */
	public static List<City> readCityFile(String filePath) throws Exception {
		List<City> cityList = new ArrayList<City>(250);
		
		File file = new File(filePath);
		
		if(!file.exists()){
			return null;
		}
		
		InputStream stream = null;
		try{
			stream = new FileInputStream(file);
			LineNumberReader reader = new LineNumberReader(new InputStreamReader(stream));
			
			String line = reader.readLine();
			int cityIndex = 0;
			StringBuilder sb = new StringBuilder();
			while (line != null) {
				line = line.trim();
				if(line.length() > 0){
					sb = new StringBuilder();
					for(int i=0; i<line.length(); i++){
						char ch = line.charAt(i); 
						if(ch == ' ' || ch == '-' || ch == '.' || ch == 'e' || ch == 'E' || Character.isDigit(ch)){
							sb.append(ch);
						}
					}
					line = sb.toString();
					line = line.replaceAll("  ", ",");
					line = line.replaceAll(" ", ",");
					
					String[] point = line.split(",");
					if(point.length == 2){
						cityList.add(new City(cityIndex++, Double.parseDouble(point[0]), Double.parseDouble(point[1])));
					}
				}
				
				line = reader.readLine();
			}
			
		} catch (Exception e){
			throw e;
		} finally {
			try{
				if(stream != null){
					stream.close();
				}
			}
			catch (IOException e){
					e.printStackTrace();
			}
		}
		
		return cityList;
	}
	
	public static void convertIntArrayToList(List<Integer> list, int[] array){
		for(int i=0; i<array.length; i++){
			list.add(i);
		}
	}
	
	public static void mergeList(List<Integer> list, List<Integer> list2){
		for(int i=0; i<list2.size(); i++){
			list.add(list2.get(i));
		}
	}
	
}
